package cn.com.oceansoft.application.common.util;

import cn.com.oceansoft.framework.kits.ApiResult;
import com.alibaba.fastjson.JSONObject;
import org.apache.commons.lang.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import redis.clients.jedis.Jedis;
import redis.clients.jedis.JedisPool;
import redis.clients.jedis.JedisPoolConfig;

import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
import java.util.Properties;

/**
 * cn.com.oceansoft.application.common.util
 * Created by smc
 * date on 2016/6/22.
 * Email:sunmch@163.com
 */
public class TokenUtils {

    private static final Logger log = LoggerFactory.getLogger(TokenUtils.class);

    private Jedis jedis = null;

    private  static TokenObj tokenObj = null;

    private static JedisPool jedisPool = null;

    private TokenUtils(){
        setTokenObj();
        this.jedis = getJedis();
    }

    private Jedis getJedis(){
       if(jedisPool == null){
           JedisPoolConfig config = new JedisPoolConfig();
           config.setMaxIdle(tokenObj.getRedisMaxIdle());
           config.setMaxTotal(tokenObj.getRedisMaxTotal());
           config.setTestOnBorrow(tokenObj.isRedisTestOnBorrow());
           log.info("判断是否包含redis密码: {}",tokenObj.getRedisAuth());
           if(StringUtils.isNotBlank(tokenObj.getRedisAuth())){
               jedisPool = new JedisPool(config,tokenObj.getRedisHost(),tokenObj.getRedisPort(),tokenObj.getRedisMaxWaitMillis(),tokenObj.getRedisAuth());
           }else{
               jedisPool = new JedisPool(config,tokenObj.getRedisHost(),tokenObj.getRedisPort(),tokenObj.getRedisMaxWaitMillis());
           }
       }
        return jedisPool.getResource();
    }

    public static TokenUtils getInstance(){
        return new TokenUtils();
    }

    public synchronized  String getToken(String url){
        String token = null;
        Map<String,String> map = new HashMap<>();
        String flag = "";
        if(url.contains("api/v1/police")||url.contains("api/v1/matters") || url.contains("api/v1/projects") || url.contains("api/v1/hzorg") || url.contains("api/v1/org")){
            map.put("appId",tokenObj.getAppCaseId());
            map.put("secrectKey",tokenObj.getSecrectCaseKey());
            flag = "case";
        }else if(url.contains("api/v1/express") || url.contains("api/v1/emspay") || url.contains("api/v1/sfpay")){
            map.put("appId",tokenObj.getAppMailId());
            map.put("secrectKey",tokenObj.getSecrectMailKey());
            flag = "mail";
        }else if(url.contains("api/v1/consults") || url.contains("api/v1/sms") || url.contains("api/v1/users") || url.contains("api/v1/profile")){
            map.put("appId",tokenObj.getAppUserId());
            map.put("secrectKey",tokenObj.getSecrectUserKey());
            flag = "user";
        }else{
            map.put("appId",tokenObj.getAppQueryId());
            map.put("secrectKey",tokenObj.getSecrectQueryKey());
            flag = "query";
        }
        token = jedis.get("hnwap:api:token:"+flag);
        log.info("redis缓存中获取的token：{}",token);
        if(StringUtils.isBlank(token)){
            String tokenUrl = tokenObj.getTokenUrl();
            String tokenResult = HttpClientUtil.doPostTokenString(tokenUrl,map);
            log.info("获取认证的tokenResult:{}",tokenResult);
            ApiResult apiResult = JSONObject.parseObject(tokenResult,ApiResult.class);
            try {
                token = apiResult.getData().toString();
                String tokenTime = HttpClientUtil.doGetToken(tokenObj.getTokenTime()+"?token="+token);
                ApiResult apiResultTime = JSONObject.parseObject(tokenTime,ApiResult.class);
                if(apiResultTime.getData() != null){
                    int time = Integer.parseInt(apiResultTime.getData().toString());
                    jedis.setex("hnwap:api:token:"+flag,time-2,token);
                }
            } catch (IOException e) {
               log.error("获取token错误: ",e);
            }
        }
        close();
        return token;
    }


    private void setTokenObj(){
        if(tokenObj ==null){
            Properties properties = new Properties();
            try {
                tokenObj  = new TokenObj();
                properties.load(TokenUtils.class.getClassLoader().getResourceAsStream("properties/token.properties"));
                log.info("获取redis的密码: {}",properties.getProperty("redis.pwd"));
                tokenObj.setRedisAuth(properties.getProperty("redis.pwd"));
                tokenObj.setRedisHost(properties.getProperty("redis.host"));
                tokenObj.setRedisPort(Integer.parseInt(properties.getProperty("redis.port")));
                tokenObj.setRedisMaxIdle(Integer.parseInt(properties.getProperty("redis.maxIdle")));
                tokenObj.setRedisMaxTotal(Integer.parseInt(properties.getProperty("redis.maxTotal")));
                tokenObj.setRedisMaxWaitMillis(Integer.parseInt(properties.getProperty("redis.maxWaitMillis")));
                tokenObj.setRedisTestOnBorrow(Boolean.parseBoolean(properties.getProperty("redis.testOnBorrow")));
                tokenObj.setTokenTime(properties.getProperty("token.time"));
                tokenObj.setTokenUrl(properties.getProperty("token.url"));

                tokenObj.setAppCaseId(properties.getProperty("token.case.appId"));
                tokenObj.setSecrectCaseKey(properties.getProperty("token.case.secrectKey"));

                tokenObj.setAppUserId(properties.getProperty("token.user.appId"));
                tokenObj.setSecrectUserKey(properties.getProperty("token.user.secrectKey"));

                tokenObj.setAppQueryId(properties.getProperty("token.query.appId"));
                tokenObj.setSecrectQueryKey(properties.getProperty("token.query.secrectKey"));

                tokenObj.setAppMailId(properties.getProperty("token.mail.appId"));
                tokenObj.setSecrectMailKey(properties.getProperty("token.mail.secrectKey"));

            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
    private void close(){
        jedis.close();
    }
}

class TokenObj{

    private String redisHost;

    private int redisPort;

    private String redisAuth;

    private int redisMaxIdle;

    private int redisMaxWaitMillis;

    private int redisMaxTotal;

    private boolean redisTestOnBorrow;

    private String TokenTime;

    private String tokenUrl;

    private String appCaseId;

    private String secrectCaseKey;

    private String appMailId;

    private String secrectMailKey;

    private String appUserId;

    private String secrectUserKey;

    private String appQueryId;

    private String secrectQueryKey;

    public String getRedisHost() {
        return redisHost;
    }

    public void setRedisHost(String redisHost) {
        this.redisHost = redisHost;
    }

    public int getRedisPort() {
        return redisPort;
    }

    public void setRedisPort(int redisPort) {
        this.redisPort = redisPort;
    }

    public String getRedisAuth() {
        return redisAuth;
    }

    public void setRedisAuth(String redisAuth) {
        this.redisAuth = redisAuth;
    }

    public int getRedisMaxIdle() {
        return redisMaxIdle;
    }

    public void setRedisMaxIdle(int redisMaxIdle) {
        this.redisMaxIdle = redisMaxIdle;
    }

    public int getRedisMaxWaitMillis() {
        return redisMaxWaitMillis;
    }

    public void setRedisMaxWaitMillis(int redisMaxWaitMillis) {
        this.redisMaxWaitMillis = redisMaxWaitMillis;
    }

    public int getRedisMaxTotal() {
        return redisMaxTotal;
    }

    public void setRedisMaxTotal(int redisMaxTotal) {
        this.redisMaxTotal = redisMaxTotal;
    }

    public boolean isRedisTestOnBorrow() {
        return redisTestOnBorrow;
    }

    public void setRedisTestOnBorrow(boolean redisTestOnBorrow) {
        this.redisTestOnBorrow = redisTestOnBorrow;
    }

    public String getTokenTime() {
        return TokenTime;
    }

    public void setTokenTime(String tokenTime) {
        TokenTime = tokenTime;
    }

    public String getTokenUrl() {
        return tokenUrl;
    }

    public void setTokenUrl(String tokenUrl) {
        this.tokenUrl = tokenUrl;
    }

    public String getAppCaseId() {
        return appCaseId;
    }

    public void setAppCaseId(String appCaseId) {
        this.appCaseId = appCaseId;
    }

    public String getSecrectCaseKey() {
        return secrectCaseKey;
    }

    public void setSecrectCaseKey(String secrectCaseKey) {
        this.secrectCaseKey = secrectCaseKey;
    }

    public String getAppMailId() {
        return appMailId;
    }

    public void setAppMailId(String appMailId) {
        this.appMailId = appMailId;
    }

    public String getSecrectMailKey() {
        return secrectMailKey;
    }

    public void setSecrectMailKey(String secrectMailKey) {
        this.secrectMailKey = secrectMailKey;
    }

    public String getAppUserId() {
        return appUserId;
    }

    public void setAppUserId(String appUserId) {
        this.appUserId = appUserId;
    }

    public String getSecrectUserKey() {
        return secrectUserKey;
    }

    public void setSecrectUserKey(String secrectUserKey) {
        this.secrectUserKey = secrectUserKey;
    }

    public String getAppQueryId() {
        return appQueryId;
    }

    public void setAppQueryId(String appQueryId) {
        this.appQueryId = appQueryId;
    }

    public String getSecrectQueryKey() {
        return secrectQueryKey;
    }

    public void setSecrectQueryKey(String secrectQueryKey) {
        this.secrectQueryKey = secrectQueryKey;
    }
}
